home *** CD-ROM | disk | FTP | other *** search
-
- /* MyApp.m */
-
- #import <objc/List.h>
- #import <appkit/Window.h>
- #import <appkit/Bitmap.h>
- #import <appkit/Listener.h>
- #import <appkit/Bitmap.h>
- #import <appkit/graphics.h>
- #import <dpsclient/psops.h>
- #import <dpsclient/wraps.h>
- #import <streams/streams.h>
- #import <libc.h>
- #import <strings.h>
- #import <pwd.h>
- #import "IconView.h"
- #import "DockSpeaker.h"
- #import "MyApp.h"
-
-
- #define READ 0
- #define DOCK_WINDOW_LEVEL (NX_MAINMENULEVEL - 1)
-
- char *mySalloc(string)
- /* returns a copy of string */
- char *string;
- {
- char *newString;
-
- newString = (char *)malloc(strlen(string) + 1);
- if (!newString) {
- return("");
- }
- strcpy(newString, string);
- return newString;
- }
-
- @implementation MyApp
-
- /* factory methods */
-
- + new
- {
- self = [super new];
-
- /* we want to be our own delegate */
- [self setDelegate:self];
-
- return self;
- }
-
-
- /* class methods */
-
- - createDockWindows:(int *)minX :(int *)minY :(int *)maxX :(int *)maxY
- /* creates the dock windows based on the .altdock file */
- {
- id dockWindowList, appBitmap;
- NXStream *fileStream;
- int fd, scanResult, success, xCoordinate, yCoordinate;
- char *homeDir, *dockFile, *appFileName;
- struct passwd *passwdEntry;
-
- /* initialize the bounding box */
- *minX = *minY = *maxX = *maxY = 0;
-
- /* create a list to hold the dock's windows */
- dockWindowList = [List new];
-
- /* get ready to ask the WorkSpace for icons */
- [[self appSpeaker] setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)];
-
- /* get the user's home directory and create the .altdock file's abs path */
- passwdEntry = getpwuid((int)getuid());
- homeDir = passwdEntry->pw_dir;
- dockFile = (char *)malloc(strlen(homeDir) + 10);
- sprintf(dockFile, "%s/.altdock", homeDir);
-
- /* open a stream on the .altdock file */
- fd = open(dockFile, READ);
- if (fd < 0) {
- NXRunAlertPanel(NULL, "Couldn't open .altdock file", NULL, NULL, NULL);
- free(dockFile);
- return dockWindowList;
- }
- fileStream = NXOpenFile(fd, NX_READONLY);
-
- while (YES) {
- /* get the window's x and y coordinates, then the app's path */
- scanResult = NXScanf(fileStream, "%d %d\n", &xCoordinate, &yCoordinate);
- if (scanResult == EOF) {
- break;
- } else if (scanResult < 2) {
- NXRunAlertPanel(NULL, "Error reading .altdock file", NULL, NULL, NULL);
- break;
- }
- appFileName = [self stringFromStream:fileStream ok:&success];
- if (!success) {
- /* we've reached the end of the .altdock file */
- NXRunAlertPanel(NULL, "Error reading .altdock file", NULL, NULL, NULL);
- break;
- }
-
- /* get the app's bitmap */
- appBitmap = [self bitmapFor:appFileName];
-
- /* create the window */
- [dockWindowList addObject:[self newIconWindowFor:appBitmap
- :xCoordinate
- :yCoordinate
- :appFileName]];
- /* adjust the bounding box */
- if (xCoordinate < *minX) *minX = xCoordinate;
- if (yCoordinate < *minY) *minY = yCoordinate;
- if (xCoordinate > *maxX) *maxX = xCoordinate;
- if (yCoordinate > *maxY) *maxY = yCoordinate;
- free(appFileName);
- }
-
- /* clean up */
- NXClose(fileStream);
- free(dockFile);
-
- return dockWindowList;
- }
-
- - bitmapFor:(char *)appFileName
- {
- id bitmap;
- char tiffDataBuffer[3000], *tiffDataBufferPtr;
- int length, flag;
- NXStream *tiffDataStream;
-
- if (!strcmp("Dock", appFileName)) {
- /* assign the dock window's bitmap */
- bitmap = [Bitmap findBitmapFor:"TXeN"];
- } else {
- /* ask the WorkSpace for the app's bitmap */
- tiffDataBufferPtr = tiffDataBuffer;
- [[self appSpeaker] getFileIconFor:appFileName
- TIFF:&tiffDataBufferPtr
- TIFFLength:&length
- ok:&flag];
- /* get a stream on memory buffer holding the TIFF data */
- tiffDataStream = NXOpenMemory(tiffDataBufferPtr, length, NX_READONLY);
- bitmap = [Bitmap newFromStream:tiffDataStream];
- NXClose(tiffDataStream);
- }
-
- return bitmap;
- }
-
- - newIconWindowFor:bitmap :(int)xCoord :(int)yCoord :(char *)applicationName
- {
- NXRect windowRect;
- id iconWindow, iconView;
-
- /* compute the new window's screen location */
- windowRect.origin.x = 4.0 + 64.0 * xCoord;
- windowRect.origin.y = 0.0 + 64.0 * yCoord;
- windowRect.size.height = windowRect.size.width = 64.0;
-
- /* create a new window */
- iconWindow = [Window newContent:&windowRect
- style:NX_PLAINSTYLE
- backing:NX_BUFFERED
- buttonMask:0
- defer:YES];
-
- /* create an iconView to go in this window */
- iconView = [IconView new:applicationName :bitmap :xCoord :yCoord];
-
- /* stick the iconView in the window */
- [iconWindow setContentView:iconView];
-
- /* make the view the window's delegate and first responder */
- [iconWindow setDelegate:iconView];
- [iconWindow makeFirstResponder:iconView];
-
- /* create the PostScript window and stick it in the screen list */
- [iconWindow makeKeyAndOrderFront:self];
-
- /* set the window's level in the screen list to be just below menus */
- _NXSetWindowLevel([iconWindow windowNum], DOCK_WINDOW_LEVEL);
-
- return iconWindow;
- }
-
- - (char *)stringFromStream:(NXStream *)fileStream ok:(int *)success
- /* reads a newline-terminated string from a stream */
- {
- char stringBuffer[1024];
- int nextChar, characterNumber = 0;
-
- while ((nextChar = NXGetc(fileStream)) != '\n') {
- /* make sure we haven't reached the end of the file */
- if (nextChar == EOF) {
- *success = 0;
- return "";
- }
- stringBuffer[characterNumber++] = (char)nextChar;
- }
- stringBuffer[characterNumber] = '\0';
- *success = 1;
-
- /* create space for the string, copy it, and return the new string */
- return mySalloc(stringBuffer);
- }
-
-
- /* delegation methods */
-
- - appDidInit:sender
- {
- id dockWindowList, dockWindow;
- int minX, minY, maxX, maxY, i;
-
- /* we need to use our own special Speaker class object */
- [self setAppSpeaker:[DockSpeaker new]];
-
- /* create the dock's windows */
- dockWindowList = [self createDockWindows:&minX :&minY :&maxX :&maxY];
-
- /* find the dock window (the one with the backward NeXT) */
- i = [dockWindowList count];
- while (i--) {
- dockWindow = [dockWindowList objectAt:i];
- if ([[dockWindow contentView] theDock]) {
- break;
- }
- }
-
- if ([[dockWindow contentView] theDock]) {
- /* give the dock window the bounding box of all of the windows */
- [[dockWindow contentView] initialize:dockWindowList
- :minX
- :minY
- :maxX
- :maxY];
- }
-
- return self;
- }
-
- @end
-